package com.lanyam.travel.base.controller;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import com.aliyuncs.utils.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lanyam.travel.base.annotation.NoRepeatSubmit;
import com.lanyam.travel.base.entity.GoodsDate;
import com.lanyam.travel.base.entity.GoodsInfo;
import com.lanyam.travel.base.entity.PanicBuy;
import com.lanyam.travel.base.entity.Product;
import com.lanyam.travel.base.entity.ScenicHotel;
import com.lanyam.travel.base.entity.SupplierInfo;
import com.lanyam.travel.base.entity.TravelLine;
import com.lanyam.travel.base.entity.TravelOrder;
import com.lanyam.travel.base.entity.TravelOrderDetails;
import com.lanyam.travel.base.entity.User;
import com.lanyam.travel.base.entity.vo.PanicBuyVo;
import com.lanyam.travel.base.service.IGoodsDateService;
import com.lanyam.travel.base.service.IOrderUserService;
import com.lanyam.travel.base.service.IPanicBuyService;
import com.lanyam.travel.base.service.IScenicHotelService;
import com.lanyam.travel.base.service.ISupplierInfoService;
import com.lanyam.travel.base.service.ITravelLineService;
import com.lanyam.travel.base.service.ITravelOrderDetailsService;
import com.lanyam.travel.base.service.ITravelOrderService;
import com.lanyam.travel.base.service.UserService;
import com.lanyam.travel.base.service.impl.OrderUserServiceImpl;
import com.lanyam.travel.base.utils.Constant;
import com.lanyam.travel.base.utils.JSONResult;
import com.lanyam.travel.base.utils.SendSMSUtils;

@RestController
@RequestMapping("panicBuy")
public class PanicBuyController {

	@Autowired
	private IPanicBuyService panicBuyService;
	
	@Autowired
	private ITravelOrderService travelOrderService;
	
	@Autowired
	private UserService userService;
	
	@Autowired
	private ITravelLineService travelLineService;
	
	@Autowired
	private IScenicHotelService scenicHotelService;
	
	@Autowired
	private IGoodsDateService goodsDateService;
	
	@Autowired
	private ISupplierInfoService supplierInfoService;

	private Lock lock = new ReentrantLock();

	/**
	 * 添加一条抢购信息
	 * @param panicBuy
	 * @return
	 * @throws ParseException 
	 */
	@RequestMapping("/addPanicBuy")
	public JSONResult addPanicBuy(@RequestBody PanicBuy panicBuy) throws ParseException
	{
		if(null == panicBuy)
		{
			return JSONResult.errorMsg("未获取到请购信息。");
		}
		String id = UUID.randomUUID().toString().replace("-", "");
		panicBuy.setId(id);
		panicBuy.setStatus(Constant.STATUS_NOT_START);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
		Date startDate = sdf.parse(panicBuy.getStartTime());
		Date endDate = sdf.parse(panicBuy.getEndTime());
		panicBuy.setStartDate(startDate);
		panicBuy.setEndDate(endDate);
		if(panicBuy.getGoodType() < 2)
		{
			ScenicHotel scenic = scenicHotelService.getScenicById(panicBuy.getGoodsId());
			if(null != scenic)
			{
				panicBuy.setSupplierId(scenic.getSupplyId());
			}
		}
		else
		{
			TravelLine line = travelLineService.getTravelLineById(panicBuy.getGoodsId());
			if(null != line)
			{
				panicBuy.setSupplierId(line.getSupplyId());
			}
		}
		panicBuyService.addPanicBuy(panicBuy);
		return JSONResult.ok(panicBuy);
	}
	/**
	 * 根据当前登陆的用户和产品类型获取产品，如果登陆的是供应商，则获取该供应商下的产品，如果是管理员，则获取所有
	 * @param userId 当前登陆用户的id
	 * @param productType 根据前台传的类型获取产品列表：0为景点，1为酒店，2为国外游，3为国内游	
	 * @return
	 */
	@PostMapping("/getProductByUserAndType")
	public JSONResult getProductByUserAndType(String userId,int productType)
	{
		if(StringUtils.isEmpty(productType+"")||StringUtils.isEmpty(userId))
		{
			return JSONResult.errorMsg("参数不全");
		}
		List<Product> products = panicBuyService.getProductByUserAndType(userId,productType);
		return JSONResult.ok(products);
	}
	/**
	 * 获取抢购列表分页数据
	 * @param reqMap 查询参数：goodType:0为景点，1为酒店，2为国外游，3为国内游,startDate:抢购开始时间，精确到天,endDate:抢购结束时间，精确到天
	 * status：抢购的状态,0抢购未开始，1进行中，2抢购已结束',goodsName:抢购的商品名称,supplierId:供应商id，如果有该值，获取的是该供应商下维护的抢购，没有则不区分供应商
	 * @return
	 */
	@RequestMapping(value = "/getAllPanicBuy", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
	public JSONResult getAllPanicBuy(@RequestBody Map<String,Object> reqMap)
	{
		String page =  reqMap.get("page").toString();
		String pageSize = reqMap.get("pageSize").toString();
		if(StringUtils.isEmpty(page)||StringUtils.isEmpty(pageSize))
		{
			return JSONResult.errorMsg("参数不全");
		}
		
		Page<PanicBuyVo> panicBuyPage = panicBuyService.getPanicBuyPage(Integer.parseInt(page),Integer.parseInt(pageSize) ,reqMap);
		return JSONResult.ok(panicBuyPage);
	}
	/**
	 * 更新某一个抢购信息
	 * @param panicBuy
	 * @return
	 */
	@RequestMapping("/updatePanicBuy")
	public JSONResult updatePanicBuy(PanicBuy panicBuy)
	{
		if(panicBuy.getGoodType() < 2)
		{
			ScenicHotel scenic = scenicHotelService.getScenicById(panicBuy.getGoodsId());
			if(null != scenic)
			{
				panicBuy.setSupplierId(scenic.getSupplyId());
			}
		}
		else
		{
			TravelLine line = travelLineService.getTravelLineById(panicBuy.getGoodsId());
			if(null != line)
			{
				panicBuy.setSupplierId(line.getSupplyId());
			}
		}
		panicBuyService.updatePanicBuy(panicBuy);
		return JSONResult.ok();
	}
	/**
	 * 删除某个抢购信息
	 * @param id 
	 * @return
	 */
	@RequestMapping("/deletePanicBuy")
	public JSONResult deletePanicBuy(String id)
	{
		panicBuyService.deletePanicBuyById(id);
		return JSONResult.ok();
	}
	/**
	 * 根据id获取抢购信息
	 * @param id
	 * @return
	 */
	@PostMapping("/getPanicBuyById")
	public JSONResult getPanicBuyById(String id)
	{
		PanicBuyVo panicVo = panicBuyService.queryPanicBuyInfoById(id);
		return JSONResult.ok(panicVo);
	}
	
	/**
	 * 更新抢购的状态
	 * @param id
	 * @param status 0抢购未开始，1进行中，2抢购已结束
	 * @return
	 */
	@PostMapping("/updatePanicBuyStatus")
	public JSONResult updatePanicBuyStatus(String id,int status)
	{
		panicBuyService.updatePanicBuyStatus(id,status);
		return JSONResult.ok();
	}
	
	/**
	 * 获取未来30天的差价
	 * @param productId 景区/线路/酒店id
	 * @return
	 */
	@PostMapping("/getDisparityByDate")
	public JSONResult getDisparityByDate(String month,String productId)
	{
		if(StringUtils.isEmpty(productId))
		{
			return JSONResult.errorMsg("请求参数不全.");
		}
		Product product = scenicHotelService.getScenicById(productId);
		//如果是线路
		if(null == product)
		{
			product = travelLineService.getTravelLineById(productId);
		}
		//把商品日期表更新到30天
		Calendar calendar = Calendar.getInstance();//获取当前日期0点的时候（00：00：00-24：00：00）
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		Date latestDate = goodsDateService.getLatestDate(productId);
		int days = Constant.TICKET_DAYS;
		Calendar afterCalendar;
		if(null != latestDate )
		{
			afterCalendar = Calendar.getInstance();
			afterCalendar.setTime(latestDate);//目标日期的时间点
			afterCalendar.set(Calendar.HOUR_OF_DAY, 0);
			afterCalendar.set(Calendar.MINUTE, 0);
			afterCalendar.set(Calendar.SECOND, 0);
			afterCalendar.set(Calendar.MILLISECOND, 0);
			days = (int)Math.ceil((afterCalendar.getTimeInMillis() - calendar.getTimeInMillis()) / (1000.0 * 60 * 60 * 24));
			days = Constant.TICKET_DAYS - 1 - days;
			afterCalendar.add(Calendar.DAY_OF_YEAR, 1);//增加最新日期的下一天
			if(days<0)
			{
				days = 0;
			}
		}
		else
		{
			afterCalendar = calendar;
		}
		List<GoodsDate> addGoodsDateList = new ArrayList<GoodsDate>();
		GoodsDate goodsDate;
		for (int i = 0; i < days; i++) {
			goodsDate = new GoodsDate();
			goodsDate.setGoodsId(productId);
			goodsDate.setPrice(product.getPrice());
			goodsDate.setRemaindNum(product.getTotalNum());
			goodsDate.setProductType(product.getProductType());
			goodsDate.setPriceDisparity(0);
			goodsDate.setTheDate(new Timestamp(afterCalendar.getTimeInMillis()));//设置固定的时间为8：00：00
			System.out.println("时间为："+afterCalendar.getTime());
			addGoodsDateList.add(goodsDate);
			afterCalendar.add(Calendar.DAY_OF_YEAR, 1);
		}
		if(addGoodsDateList.size() > 0)
		{
			goodsDateService.batchAddGoodsDates(addGoodsDateList);
		}
		//查询未来30天每天的余票数
		List<GoodsDate> goodsDateInMouth = goodsDateService.queryGoodsDateByMouth(productId, month);
		return JSONResult.ok(goodsDateInMouth);
	}
	/**
	 * 更新某一天的差价
	 * @param goodsDate
	 * @return
	 */
	@RequestMapping("/updateDisparity")
	public JSONResult updateDisparity(GoodsDate goodsDate)
	{
		goodsDateService.updateGoodsDate(goodsDate);
		return JSONResult.ok();
	}
	/**
	 * 批量更新商品抢购差价
	 * @param productId 商品详情id
	 * @param startDate 开始日期
	 * @param endDate 结束日期
	 * @param disparity 差价
	 * @return
	 */
	@PostMapping("/batchUpdateDisparity")
	public JSONResult batchUpdateDisparity(String productId,String startDate,String endDate,double disparity)
	{
		if(StringUtils.isEmpty(productId)||StringUtils.isEmpty(startDate)||StringUtils.isEmpty(endDate))
		{
			return JSONResult.errorMsg("参数不全");
		}
		List<GoodsDate> list = goodsDateService.queryGoodsDateInDays(productId, startDate,endDate);
		if(null != list && list.size() > 0)
		{
			for (GoodsDate goodsDate : list) {
				goodsDate.setPriceDisparity(disparity);
			}
			goodsDateService.batchUpdateGoodsDate(list);
			return JSONResult.ok();
		}
		else
		{
			return JSONResult.errorMsg("更新日历失败");
		}
	}
	
	/**
	 * 抢购功能实现
	 * @param panicBuyId 抢购id
	 * @param userId 抢购人id
	 * @return
	 */
	@RequestMapping("/killBuy")
	@NoRepeatSubmit
	public JSONResult killBuy(String panicBuyId,String userId)
	{
		Boolean result=false;
		if(StringUtils.isEmpty(panicBuyId) || StringUtils.isEmpty(userId)) 
		{
			return JSONResult.errorMsg("信息不全，不能参与抢购。");
		}
		try {
			lock.lock();
			//TODO:判断当前用户是否已经抢购过当前商品
			int queryPanicBuyCount = travelOrderService.queryPanicBuyCount(panicBuyId,userId);
			if(queryPanicBuyCount <= 0)
			{
				//TODO:查询待秒杀详情
				PanicBuy panicBuy = panicBuyService.queryPanicBuyById(panicBuyId);
				User user = userService.queryUserById(userId);
				if(null != panicBuy && panicBuy.getStatus() == 1)
				{
					//TODO 这里需要处理，可能有多线程问题
					int rest = panicBuy.getTotalNum();
					if(rest > 0)
					{
						panicBuy.setTotalNum(rest--);
						if(rest == 0)
						{
							panicBuy.setStatus(Constant.STATUS_STOP);
						}
						panicBuyService.updatePanicBuy(panicBuy);
						//TODO 创建订单
						TravelOrder order = new TravelOrder();
						String orderId = UUID.randomUUID().toString().replace("-", "");
						order.setId(orderId);
						order.setOrderType(1);
						order.setOrderUserid(userId);
						order.setOrderUsername(user.getName());
						Calendar calendar = Calendar.getInstance();
						order.setOrderTime(calendar.getTime());
						order.setOrderAmount(new BigDecimal(panicBuy.getPrice()));
						order.setPayStatus(0);
						calendar.add(Calendar.DAY_OF_YEAR, panicBuy.getEffectDays());
						order.setOverrdueTime(calendar.getTime());
						Product product = panicBuy.getProduct();
						if(null != product)
						{
							order.setSupplyId(product.getSupplyId());
						}
						order.setProductId(panicBuy.getGoodsId());
						travelOrderService.addOrder(order);
						//订单详细记录和商品日期对应的价格在预定中创建
						SupplierInfo supply = supplierInfoService.getSupplierById(product.getSupplyId());
						String phone = "";
						if(null != supply)
						{
							phone = supply.getContTel();
						}
						//发送抢购成功短信
						Map<String,String> paramMap = new HashMap<String, String>();
						paramMap.put("name", user.getName());
						paramMap.put("shopname", product.getName());
						paramMap.put("orderid", orderId);
						SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
						String overdueDate = sdf.format(order.getOverrdueTime());
						paramMap.put("date", overdueDate);
						paramMap.put("telphone",phone);
						SendSMSUtils.doSend(user.getPhone(), paramMap, "SMS_180342369");
						return JSONResult.ok("恭喜你，抢购成功。");
					}
					else
					{
						return JSONResult.errorMsg("订单已经抢购完毕。");
					}
				}
				else
				{
					return JSONResult.errorMsg("对不起，抢购订单暂时处于关闭状态。");
				}
			}
			else
			{
				return JSONResult.errorMsg("您已经抢购过该订单。");
			}
			
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return JSONResult.errorMsg("系统忙碌中，请稍后重试");
		}finally {
			lock.unlock();
		}
		
	}
	
}
